package ca.csf.dfc.poo.iu;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import ca.csf.dfc.poo.bots.RobotGreedy;
import ca.csf.dfc.poo.bots.RobotIntelligent;
import ca.csf.dfc.poo.bots.RobotRandom;
import ca.csf.dfc.poo.eng.Engine;


/**
 * Classe représentant l'interface utilisé pour l'ajout de robots dans un environnement lors d'une simulation.
 * 
 * @author Jean-François Bédard, Marie-Pier Chabot, 
 * Alexandre Paquet Fasys, Claude Roy
 *
 */
public class AjouterRobot extends JDialog
{
	private static final long serialVersionUID = 1L;
	
	/**
	 * L'engine qui contiendra les robots ajoutés
	 */
	public Engine m_Engine;
	
	//Création des étiquettes
	/**
	 * Label pour le type de robot
	 */
	JLabel lblType = new JLabel("Type");
	/**
	 * Label pour le robot intelligent
	 */
	JLabel lblIntelligent = new JLabel("Intelligent :");
	/**
	 * Label pour le robot vorace
	 */
	JLabel lblVorace = new JLabel("Vorace :");
	/**
	 * Label pour le robot aléatoire
	 */
	JLabel lblAleatoire = new JLabel("Aleatoire :");
	/**
	 * Label pour la quantité de robots ajoutés
	 */
	JLabel lblQuantite = new JLabel("Quantite");
	
	//Création des listes déroulantes
	/**
	 * Modèle de ComboBox pour le choix du nombre de robots intelligents
	 */
	DefaultComboBoxModel modcmbIntelligent = new DefaultComboBoxModel();
	/**
	 * Modèle de ComboBox pour le choix du nombre de robots voraces
	 */
	DefaultComboBoxModel modcmbVorace = new DefaultComboBoxModel();
	/**
	 * Modèle de ComboBox pour le choix du nombre de robots aléatoires
	 */
	DefaultComboBoxModel modcmbAleatoire = new DefaultComboBoxModel();
	/**
	 * ComboBox pour le choix du nombre de robots intelligents
	 */
	JComboBox cmbIntelligent = new JComboBox(modcmbIntelligent);
	/**
	 * ComboBox pour le choix du nombre de robots voraces
	 */
	JComboBox cmbVorace = new JComboBox(modcmbVorace);
	/**
	 * ComboBox pour le choix du nombre de robots aléatoires
	 */
	JComboBox cmbAleatoire = new JComboBox(modcmbAleatoire);
	
	//Création des boutons
	/**
	 * Bouton pour l'ajout définitif des robots à l'evironnement
	 */
	JButton btnAjouter = new JButton("Ajouter");
	/**
	 * Bouton pour annuler l'ajout et retouner à l'interface principale
	 */
	JButton btnAnnuler = new JButton("Annuler");
	
	/**
	 * Constructeur par initialisation.
	 * 
	 * @param p_parent L'interface parent (dans ce cas particulier, l'interface principale)
	 * @param p_Engine L'engin régissant la simulation
	 */
	public AjouterRobot(JFrame p_parent, Engine p_Engine)
	{
		super(p_parent, "Ajouter un/des robot(s)", true);
		m_Engine = p_Engine;
				
		Container c = this.getContentPane();
		c.setLayout(new BorderLayout());
		
		JPanel panneauGauche = new JPanel();
		JPanel panneauDroite = new JPanel();
		JPanel panneauBas = new JPanel();
		
		panneauGauche.setLayout(new GridLayout(4,1));
		panneauDroite.setLayout(new GridLayout(4,1));
		
		//Ajout des étiquettes dans le panneau de gauche
		panneauGauche.add(this.lblType);
		panneauGauche.add(this.lblIntelligent);
		panneauGauche.add(this.lblVorace);
		panneauGauche.add(this.lblAleatoire);
		
		//Ajout d'une étiquette et des listes déroulantes dans le panneau de droite
		panneauDroite.add(this.lblQuantite);
		panneauDroite.add(this.cmbIntelligent);
		panneauDroite.add(this.cmbVorace);
		panneauDroite.add(this.cmbAleatoire);
		
		//Ajout de boutons dans le panneau du bas
		panneauBas.add(this.btnAjouter);
		panneauBas.add(this.btnAnnuler);
		
		//Ajout des trois panneaux dans le GridLayout
		c.add(panneauGauche, BorderLayout.WEST);
		c.add(panneauDroite, BorderLayout.EAST);
		c.add(panneauBas, BorderLayout.SOUTH);
		
		//Appel de la méthode pour remplir les listes déroulantes
		ChargerComboBox(p_Engine);
		
		this.pack();
		this.setResizable(false);
		this.setLocationRelativeTo(null);
		
		//Les événements reliés aux boutons
		GestionDesBoutons gestiondesboutons = new GestionDesBoutons();
		this.btnAjouter.addActionListener(gestiondesboutons);
		this.btnAnnuler.addActionListener(gestiondesboutons);
		
		//Les événements reliés aux listes déroulantes
		GestionComboBox gestionComboBox = new GestionComboBox();
		this.cmbAleatoire.addActionListener(gestionComboBox);
		this.cmbIntelligent.addActionListener(gestionComboBox);
		this.cmbVorace.addActionListener(gestionComboBox);
	}
	
	/**
	 * Cette méthode permet de remplir les 3 listes déroulantes au départ.
	 * 
	 * @param p_Engine L'engin régissant la simulation
	 */
	private void ChargerComboBox(Engine p_Engine)
	{
		//Ajout de l'élément 0
		this.modcmbAleatoire.addElement(0);
		this.modcmbIntelligent.addElement(0);
		this.modcmbVorace.addElement(0);
		
		//Ajout des autres éléments
		for(int i = 0; i < (20 - p_Engine.getListRobots().size()); i++)
		{
			this.modcmbAleatoire.addElement(i+1);
			this.modcmbIntelligent.addElement(i+1);
			this.modcmbVorace.addElement(i+1);
		}
	}
	
	/**
	 * Gestionnaire des événements reliés aux listes déroulantes.
	 * 
	 * @author Jean-François Bédard, Marie-Pier Chabot, Alexandre Paquet Fasys, Claude Roy
	 */
	public class GestionComboBox implements ActionListener
	{
		
		/**
		 * Méthode pour gérer le choix d'une option dans un combobox.
		 */
		@Override
		public void actionPerformed(ActionEvent p_e) 
		{
			//Rechargement de deux listes déroulantes en fonction de la sélection dans l'autre 
			//liste déroulante
			this.reChargerComboBox(p_e);
		}
		
		/**
		 * Cette méthode permet d'ajuster le nombre d'éléments de deux listes déroulantes
		 * en fonction de la sélection du nombre d'éléments dans l'autre liste déroulante
		 * @param p_e	Événement entraînant les changements (trois listes déroulantes, donc
		 * trois possibilités)
		 */
		private void reChargerComboBox(ActionEvent p_e)
		{
			int indexcmbIntelligent = AjouterRobot.this.cmbIntelligent.getSelectedIndex();
			int indexcmbVorace = AjouterRobot.this.cmbVorace.getSelectedIndex();
			int indexcmbAleatoire = AjouterRobot.this.cmbAleatoire.getSelectedIndex();
			int nombreRobotTotal = indexcmbAleatoire + indexcmbIntelligent + indexcmbVorace;
			
			//La taille de la liste déroulante des robots intelligents est ajustée
			
			//Suppression d'éléments dans la liste
			if(AjouterRobot.this.modcmbIntelligent.getSize()-1 > (20 - nombreRobotTotal+ indexcmbIntelligent)
					&& (p_e.getSource() != AjouterRobot.this.cmbIntelligent))
			{
				for(int i = AjouterRobot.this.modcmbIntelligent.getSize() -1; i > (20 - nombreRobotTotal + indexcmbIntelligent); i--)
				{
					AjouterRobot.this.modcmbIntelligent.removeElementAt(i);
				}
			}
			
			//Ajout d'éléments dans la liste
			else if ((AjouterRobot.this.modcmbIntelligent.getSize()-1 <= (20 - nombreRobotTotal+ indexcmbIntelligent)) 
					&& (p_e.getSource() != AjouterRobot.this.cmbIntelligent))
			{
				for(int i = AjouterRobot.this.modcmbIntelligent.getSize() -1; i < (20 - nombreRobotTotal + indexcmbIntelligent); i++)
				{
					AjouterRobot.this.modcmbIntelligent.addElement(i+1);
				}
			}
			
			//La taille de la liste déroulante des robots voraces est ajustée
			
			//Suppression d'éléments dans la liste
			if (((AjouterRobot.this.modcmbVorace.getSize()-1) > (20 - nombreRobotTotal+ indexcmbVorace))
					&& (p_e.getSource() != AjouterRobot.this.cmbVorace))
			{
				for(int i = AjouterRobot.this.modcmbVorace.getSize() -1; i > (20 - nombreRobotTotal + indexcmbVorace); i--)
				{
					AjouterRobot.this.modcmbVorace.removeElementAt(i);
				}
			}
			
			//Ajout d'éléments dans la liste
			else if ((AjouterRobot.this.modcmbVorace.getSize()-1 <= (20 - nombreRobotTotal + indexcmbVorace)) 
					&& (p_e.getSource() != AjouterRobot.this.cmbVorace))
			{
				for(int i = AjouterRobot.this.modcmbVorace.getSize() -1; i < (20 - nombreRobotTotal+ indexcmbVorace); i++)
				{
					AjouterRobot.this.modcmbVorace.addElement(i+1);
				}
			}
			
			//La taille de la liste déroulante des robots aléatoires est ajustée
			
			//Suppression d'éléments dans la liste
			if((AjouterRobot.this.modcmbAleatoire.getSize()-1 > (20 - nombreRobotTotal+ indexcmbAleatoire)) 
					&& (p_e.getSource() != AjouterRobot.this.cmbAleatoire))
			{
				for(int i = AjouterRobot.this.modcmbAleatoire.getSize() -1; i > (20 - nombreRobotTotal + indexcmbAleatoire); i--)
				{
					AjouterRobot.this.modcmbAleatoire.removeElementAt(i);
				}
			}
			
			//Ajout d'éléments dans la liste
			else if ((AjouterRobot.this.modcmbAleatoire.getSize()-1 <= (20 - nombreRobotTotal+ indexcmbAleatoire)) 
					&& (p_e.getSource() != AjouterRobot.this.cmbAleatoire))
			{
				for(int i = AjouterRobot.this.modcmbAleatoire.getSize() -1; i < (20 - nombreRobotTotal + indexcmbAleatoire); i++)
				{
					AjouterRobot.this.modcmbAleatoire.addElement(i+1);
				}
			}
		}
	}
	
	/**
	 * Gestionnaire des événements reliés aux boutons
	 * 
	 * @author Jean-François Bédard, Marie-Pier Chabot, Alexandre Paquet Fasys, Claude Roy
	 */
	public class GestionDesBoutons implements ActionListener
	{
		/**
		 * Méthode pour gérer les cliques sur les boutons «Ajouter» et «Annuler».
		 */
		@Override
		public void actionPerformed(ActionEvent p_e) 
		{
			//pour le bouton "Ajouter"
			if(p_e.getSource() == AjouterRobot.this.btnAjouter)
			{
				Random monRandom = new Random(0);
				
				//Ajout d'un robot intelligent
				for(int i = 0; i < AjouterRobot.this.cmbIntelligent.getSelectedIndex(); i++)
				{
					RobotIntelligent nouveauRobotInt = new RobotIntelligent(AjouterRobot.this.m_Engine.getEnvironnement(), 
																			AjouterRobot.this.m_Engine.getEnvironnement().getWidth(), 
																			AjouterRobot.this.m_Engine.getEnvironnement().getHeight(),  
																			monRandom);
					AjouterRobot.this.m_Engine.addRobot(nouveauRobotInt);
				}
				
				//Ajout d'un robot vorace
				for(int i = 0; i < AjouterRobot.this.cmbVorace.getSelectedIndex(); i++)
				{
					RobotGreedy nouveauRobotVor = new RobotGreedy(AjouterRobot.this.m_Engine.getEnvironnement(), monRandom);
					AjouterRobot.this.m_Engine.addRobot(nouveauRobotVor);
				}
				
				//Ajout d'un robot aléatoire
				for(int i = 0; i < AjouterRobot.this.cmbAleatoire.getSelectedIndex(); i++)
				{
					RobotRandom nouveauRobotRan = new RobotRandom(AjouterRobot.this.m_Engine.getEnvironnement(), monRandom);
					AjouterRobot.this.m_Engine.addRobot(nouveauRobotRan);
				}
				
				AjouterRobot.this.dispose();
			}
			
			//pour le bouton "Annuler"
			else if(p_e.getSource() == AjouterRobot.this.btnAnnuler)
			{
				AjouterRobot.this.dispose();
			}
			else
			{
				JOptionPane.showMessageDialog(null, "Vous ne devriez pas vous trouver ici", "Erreur", JOptionPane.ERROR_MESSAGE);
			}
		}
	}
}







